TrivyでCloudFormationやTerraformのテンプレートを静的セキュリティスキャン可能になっていたので試してみた
こんにちは。枡川です。
Trivyをコンテナイメージの脆弱性スキャン時に便利なOSSと思っていたのですが、その認識は誤っていたようです。
イメージスキャンに加えて、CloudFormationやTerraformなどのIaC設定ファイルについてもセキュリティスキャンが可能になっていました。
Aqua SecurityからCloudFormation対応時のブログも出ています。
上記ブログの序文を引用すると、tfsecの技術とルールセットを使用してCloudFormationについても評価できるようになったようです。
Aqua Security’s open source project Trivy now includes scanning of AWS CloudFormation templates to help developers better identify and remediate security issues within infrastructure as code (IaC) templates. Building on the technology and rule sets behind our popular open source project tfsec, Trivy now allows developers to evaluate AWS CloudFormation code, either locally or within their pipeline, for configuration issues and violations of best-practice policies.
めちゃくちゃ便利そうなので試してみました!
Macでインストール
homebrewでインストールできます。
brew install aquasecurity/trivy/trivy
apt-getやyumでもインストールできます。
今回は2022年3月7日時点での最新版にあたるversion0.24.2を使用します。
やってみた
対象となる設定ファイルは下記4種類となります。
- Terraform
- CloudFormation
- Kubernetes
- Dockerfile
単純なS3+CloudFrontの構成を作成する下記のようなテンプレートを作成してスキャンを実行してみます。
AWSTemplateFormatVersion: "2010-09-09" Parameters: SystemName: Type: String EnvironmentName: Type: String CfSslCertificateId: Type: String Resources: AssetsBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${SystemName}-${EnvironmentName}-bucket PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true AssetsBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref AssetsBucket PolicyDocument: Statement: - Action: s3:GetObject Effect: Allow Principal: CanonicalUser: !GetAtt 'OriginAccessIdentity.S3CanonicalUserId' Resource: !Join - / - - !GetAtt 'AssetsBucket.Arn' - '*' Distribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: CustomErrorResponses: - ErrorCachingMinTTL: 30 ErrorCode: 403 ResponseCode: 200 ResponsePagePath: /404.html DefaultCacheBehavior: ForwardedValues: QueryString: true TargetOriginId: !Sub 'S3-${AssetsBucket}' ViewerProtocolPolicy: redirect-to-https Aliases: - !Ref CfDomainName ViewerCertificate: AcmCertificateArn: !Sub "arn:aws:acm:us-east-1:${AWS::AccountId}:certificate/${CfSslCertificateId}" SslSupportMethod: sni-only DefaultRootObject: index.html Enabled: true HttpVersion: 'http2' Origins: - DomainName: !Sub '${AssetsBucket}.s3.amazonaws.com' Id: !Sub 'S3-${AssetsBucket}' S3OriginConfig: OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${OriginAccessIdentity}' OriginAccessIdentity: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: sample
設定ファイルのセキュリティスキャンを実行する際にはサブコマンドとしてconfigを使用します。(イメージスキャン時のサブコマンドはimageになっています。)
$ trivy config template.yml 2022-03-07T11:54:52.718+0900 INFO Detected config files: 1 . (cloudformation) ================== Tests: 14 (SUCCESSES: 7, FAILURES: 7, EXCEPTIONS: 0) Failures: 7 (UNKNOWN: 0, LOW: 0, MEDIUM: 3, HIGH: 4, CRITICAL: 0) +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | Cloudformation Security Check | AVD-AWS-0010 | Cloudfront distribution should have | MEDIUM | Distribution does not have logging | | | | Access Logging configured | | enabled. | + +--------------+------------------------------------------+----------+------------------------------------------+ | | AVD-AWS-0011 | CloudFront distribution does not have a | HIGH | Distribution does not utilise a WAF. | | | | WAF in front. | | | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0013 | CloudFront distribution uses outdated | | Distribution allows unencrypted | | | | SSL/TLS protocols. | | communications. | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0088 | Unencrypted S3 bucket. | | Bucket does not have encryption enabled | + +--------------+------------------------------------------+----------+------------------------------------------+ | | AVD-AWS-0089 | S3 Bucket does not have logging enabled. | MEDIUM | Bucket does not have logging enabled | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0090 | S3 Data should be versioned | | Bucket does not have versioning enabled | + +--------------+------------------------------------------+----------+------------------------------------------+ | | AVD-AWS-0132 | S3 encryption should use Customer | HIGH | Bucket does not encrypt data with a | | | | Managed Keys | | customer managed key. | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+
7項目指摘されました。
Trivyでは、severityオプションを使用して表示する脆弱性を絞り込むことも可能です。
MEDIUMとLOWは一旦無視することにします。
ここで指定方法は表示するランクを全て指定する必要があります。
MEDIUMと指定したらMIDIUM以上はすべて表示とはなりません。
$ trivy config --severity HIGH,CRITICAL template.yml 2022-03-07T11:59:50.236+0900 INFO Detected config files: 1 . (cloudformation) ================== Tests: 10 (SUCCESSES: 6, FAILURES: 4, EXCEPTIONS: 0) Failures: 4 (HIGH: 4, CRITICAL: 0) +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | Cloudformation Security Check | AVD-AWS-0011 | CloudFront distribution does not have a | HIGH | Distribution does not utilise a WAF. | | | | WAF in front. | | | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0013 | CloudFront distribution uses outdated | | Distribution allows unencrypted | | | | SSL/TLS protocols. | | communications. | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0088 | Unencrypted S3 bucket. | | Bucket does not have encryption enabled | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0132 | S3 encryption should use Customer | | Bucket does not encrypt data with a | | | | Managed Keys | | customer managed key. | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+
WAFを使った方が良いのはわかっているんだけどお金が無いんだ!という場合は.trivyignoreというファイルを作成して、特定の指摘を無視することも可能です。
検証目的でS3のCMKを使用した暗号化を設定するのも面倒だったので、S3の暗号化はCMKを使うべきという項目もついでに無効化しておきます。
$ (echo "AVD-AWS-0011"; echo "AVD-AWS-0132") > trivyignore $ trivy config --severity HIGH template.yml 2022-03-07T14:28:45.370+0900 INFO Detected config files: 1 . (cloudformation) ================== Tests: 8 (SUCCESSES: 6, FAILURES: 2, EXCEPTIONS: 0) Failures: 2 (HIGH: 2, CRITICAL: 0) +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+ | Cloudformation Security Check | AVD-AWS-0013 | CloudFront distribution uses outdated | HIGH | Distribution allows unencrypted | | | | SSL/TLS protocols. | | communications. | + +--------------+------------------------------------------+ +------------------------------------------+ | | AVD-AWS-0088 | Unencrypted S3 bucket. | | Bucket does not have encryption enabled | +-------------------------------+--------------+------------------------------------------+----------+------------------------------------------+
指摘事項が2個残りました。
各検出結果の修正方法は下記サイトに記載があります。
上記サイトにはセキュリティスキャンの内容についてもより詳細に説明があります。
推奨される書き方も記載されているので、CloudFormationに追加します。
CloudFrontのSSL/TLSプロトコルバージョンについても指摘されているので修正します。
マネコンから作成した場合は自然と推奨されているTLSv1.2_2021を選択しそうですが、MinimumProtocolVersionを指定せずにCloudFormationスタックを作成するとTLSv1になってますね。
この手の気づき辛い内容をチェックしてくれるのは有り難いです。
下記内容に従って修正します。
ここまでやって再度チェックをかけると、エラーが0個になりました。
$ trivy config --severity HIGH,CRITICAL template.yml 2022-03-07T14:29:59.662+0900 INFO Detected config files: 1 . (cloudformation) ================== Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0) Failures: 0 (HIGH: 0, CRITICAL: 0)
ディレクトリを指定してスキャンを実施することで、当該ディレクトリにあるファイルを全て対象にすることが可能です。
DockerfileやKubernetesの定義ファイルについても同時にスキャンできます。
$ trivy config --severity HIGH,CRITICAL . 2022-03-07T14:32:44.905+0900 INFO Detected config files: 3 Dockerfile (dockerfile) ======================= Tests: 17 (SUCCESSES: 16, FAILURES: 1, EXCEPTIONS: 0) Failures: 1 (HIGH: 1, CRITICAL: 0) +---------------------------+------------+-----------+----------+------------------------------------------+ | TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE | +---------------------------+------------+-----------+----------+------------------------------------------+ | Dockerfile Security Check | DS002 | root user | HIGH | Specify at least 1 USER | | | | | | command in Dockerfile with | | | | | | non-root user as argument | | | | | | -->avd.aquasec.com/appshield/ds002 | +---------------------------+------------+-----------+----------+------------------------------------------+ deployment.yml (kubernetes) =========================== Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0) Failures: 0 (HIGH: 0, CRITICAL: 0) template.yml (cloudformation) ============================= Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0) Failures: 0 (HIGH: 0, CRITICAL: 0)
--skip-filesオプションを使用することで、Dockerfileのチェックを省いたりすることも可能です。
$ trivy config --severity HIGH,CRITICAL --skip-files Dockerfile . 2022-03-07T14:33:56.026+0900 INFO Detected config files: 2 deployment.yml (kubernetes) =========================== Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0) Failures: 0 (HIGH: 0, CRITICAL: 0) template.yml (cloudformation) ============================= Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0) Failures: 0 (HIGH: 0, CRITICAL: 0)
Terraformについてはtfsecを使用し続けるべきなのか、trivyを積極的に使用した方が良いのか難しいですね...
ローカルで実行する場合はtfsecコマンドを実行した際のレスポンスの方が下記のように詳細に記載されていて見やすい気がします。
Result #1 CRITICAL Listener for application load balancer does not use HTTPS. ───────┬──────────────────────────────────────────────────────────────────────────────────────── alb.tf Line 27 ───────┬──────────────────────────────────────────────────────────────────────────────────────── 24 │ resource "aws_lb_listener" "http" { 25 │ load_balancer_arn = aws_lb.alb.arn 26 │ port = "80" 27 │ protocol = "HTTP" 28 │ 29 │ default_action { 30 │ type = "forward" 31 │ target_group_arn = aws_lb_target_group.ecs_target_group.arn 32 │ } 33 │ } ───────┬──────────────────────────────────────────────────────────────────────────────────────── ID aws-elb-http-not-used Impact Your traffic is not protected Resolution Switch to HTTPS to benefit from TLS security features
一方、イメージスキャンで既にTrivyを使用している場合は使い方や出力が統一されているので使いやすいと思います。
cfsecのGithubは下記の記載がありますが、tfsecには特に書いていないので今までtfsecを使用している場合はそのままtfsecで良いのかなあという気もします。
The CloudFormation scanning logic is now integrated with Aquasecurity Trivy. cfsec will no longer be maintained as a stand alone scanner and Trivy should be used (引用)aquasecurity/cfsec
あくまで少し触ってみただけなので、何か明確な違い等が存在すればまたブログにしようと思います!
まとめ
サクッとインストールできて、イメージスキャンもDockerfileやCloudFormationの静的スキャンもいろんなことができるTrivyの凄さを改めて認識しました。
もっと使いこなして安全に開発していきたいですね!